#define _USE_MATH_DEFINES

# include<iostream>
# include<cmath>
# include"EquationSolver.h"

using namespace::std;

/**
* @brief 把给定方程问题移项做差转为函数求零点问题，构造相应函数
* 
*/
class Fun : public Function
{
private:
    double L, r, V;
public:
    Fun(double _L, double _r, double _V)
    {
        L = _L; r = _r; V = _V;
    };

    double operator()(double h)
    {
        return (L*(0.5*M_PI*r*r - r*r*asin(h/r) - h*sqrt(r*r-h*h)) - V);
    };
};

/**
* @brief 主函数
* 
*/
int main()
{
    cout << "Solution for Qustion E: " << endl;
    Fun f(10, 1, 12.4);
    double r = 1;
    double x1, x2, x3, y1, y2, y21, y22,  y3;

    // 应用二分法求零点
    cout << "Use the bisection method to find the depth. " << endl;
    Bisection BisSolve(0.0001, r, 0.01, 0.0001, 10, f);
    x1 = BisSolve.solve();
    y1 = f(x1);
    cout << "By bisection method, the depthof water is " << x1 << ", the error of volume is " << y1 << endl;

    // 应用牛顿迭代法求零点
    cout << "Use the Newton's method to find the depth. " << endl;
    Newton NewtonSolve(0.0001, 0.01, 10, f);
    x2 = NewtonSolve.solve();
    y2 = f(x2);
    cout << "By Newton's method, the depthof water is " << x2 << ", the error of volume is " << y2 << endl;
    // 验证所求的值和真实值误差在 0.01ft 以内
    y21 = f(x2-0.01);
    y22 = f(x2+0.01);
    cout << "Test if the real root is located at (x - 0.01, x + 0.01): ";
    cout << "f(x - 0.01) = " << y21 << ", f(x + 0.01) = " << y22 << endl;
    
    // 应用割线法求零点
    cout << "Use the secant method to find the depth. " << endl;
    Secant SecSolve(r-0.1, r-0.05, 0.01, 0.0001, 10, f);
    x3 = SecSolve.solve();
    y3 = f(x3);
    cout << "By secant method, the depthof water is " << x3 << ", the error of volume is " << y3 << endl;
    
    cout << "" << endl;
    return 0;
}